home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / PowerPlant / Multi-Panel Dialogs 1.1 / MPD Sources / UMPDialogHandler.cp < prev    next >
Encoding:
Text File  |  1996-09-13  |  12.9 KB  |  362 lines  |  [TEXT/R*ch]

  1. // ===========================================================================
  2. //    File:                        UMPDialogHandler.cp
  3. // Version:                    1.0 - Feb 1, 1996
  4. //    Author:                    Mike Shields (mshields@inconnect.com)
  5. //                            
  6. //    Copyright ©1996 Mike Shields. All rights reserved.
  7. //    I hereby grant users of UMPDialogHandler permission to use it (or any modified 
  8. //    version of it) in applications (or any other type of Macintosh software 
  9. //    like extensions -- freeware, shareware, commercial, or other) for free, 
  10. //    subject to the terms that:
  11. //
  12. //        (1)  This agreement is non-exclusive.
  13. //
  14. //        (2)  I, Mike Shields, retain the copyright to the original source code.
  15. //
  16. //    These two items are the only required conditions for use. However, I do have 
  17. //    an additional request. Note, however, that this is only a request, and 
  18. //    that it is not a required condition for use of this code.
  19. //
  20. //        (1) That I be given credit for UMPDialogHandler code in the copyrights or 
  21. //            acknowledgements section of your manual or other appropriate documentation.
  22. //
  23. //
  24. //    I would like to repeat that this last item is only a request. You are prefectly 
  25. //    free to choose not to do any or all of them.
  26. //    
  27. //        This source code is distributed in the hope that it will be useful,
  28. //        but WITHOUT ANY WARRANTY; without even the implied warranty of
  29. //        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  30. // ===========================================================================
  31. //    UMPDialogHandler.h        <- double-click + Command-D to see class declaration
  32. //
  33. // StDialogHandler subclass which is the manager of a multipanel dialog. It is
  34. // responsible for handling the creation, deletetion and all messages generated
  35. // by the main dialog controls.
  36.  
  37. #include "UMPDialogHandler.h"
  38.  
  39. #include <LWindow.h>
  40. #include <PP_Messages.h>
  41. #include <LTabGroup.h>
  42. #include <LArray.h>
  43. #include <UMemoryMgr.h>
  44.  
  45. #include "CMPDIncludeView.h"
  46. #include "CMPDPanelSelectControl.h"    
  47.  
  48. //---------------------------------------------------------------------------
  49. // StMPDialogHandler::StMPDialogHandler
  50. //---------------------------------------------------------------------------
  51. //    Constructor
  52. StMPDialogHandler::StMPDialogHandler(ResIDT inDialogResID, LCommander *inSuper,
  53.                                                 PanelIDIndexT inInitialPaneIndex, ResIDT inMPDResID)
  54.         : StDialogHandler(inDialogResID, inSuper), mCurrentPanelIndex(inInitialPaneIndex),
  55.             mIncludeView(nil), mTabGroup(nil), mPanelSelectControl(nil),
  56.             mPanelDataHandles(sizeof(Handle))
  57. {
  58.     LPane*    aPane;
  59.  
  60.     // Inititalize our include view member. This points to the view which manages
  61.     // the communication between this handler and the panel.
  62.     aPane = mDialog->FindPaneByID(MPD_IncludeView);
  63.     mIncludeView = dynamic_cast<CMPDIncludeView*>(aPane);
  64.     ThrowIfNil_(mIncludeView);
  65.     
  66.     // Now get the MPDPaneSelectControl.
  67.     aPane = mDialog->FindPaneByID(MPD_PanelSelectControl);
  68.     mPanelSelectControl = dynamic_cast<CMPDPanelSelectControl*>(aPane);
  69.     ThrowIfNil_(mPanelSelectControl);
  70.  
  71.     UpdateMenus();
  72.     
  73.     // now we go about the process the populating the PanelSelect control. We load in the 
  74.     // definition resource from field, interate through it and add a PanelID to the
  75.     // control for each item in it. Then we select the item to be the displayed one in the 
  76.     // control
  77.     mMPDData.Load('MPD#', inMPDResID, true, false);
  78.     {
  79.         StHandleLocker    locker(mMPDData);
  80.         mPanelSelectControl->InsertPanelIDs(*(MPDHandle)mMPDData);
  81.     }
  82.  
  83.     // Our internal storage needs to be initialized at this time. We pass in a pointer to a nil
  84.     // handle so we can flag panels which have not been visited before later in the code.
  85.     Handle    panelData = nil;
  86.     mPanelDataHandles.InsertItemsAt((**(MPDHandle)mMPDData).numItems, LArray::index_First, &panelData);
  87.  
  88.     mPanelSelectControl->SelectPanelID(mCurrentPanelIndex);
  89.     
  90.     // We want to know about things that happen to the control.
  91.     mPanelSelectControl->ConnectToHandler(this);
  92.     
  93.     // now we select the dialog so we can begin processing it.
  94.     mDialog->Select();
  95.  
  96.     // before we show the dialog, but after we select it (so we make it the target) we need
  97.     // to walk it's command chain looking for the TabGroup associated with the window (if
  98.     // there is one). If we find it we store a pointer to it so we can use it later when we
  99.     // are switching panels so we get the correct tab behavior.
  100.     LCommander* aSub = LCommander::GetTarget();
  101.     while ( aSub != nil )
  102.     {
  103.         if ( dynamic_cast<LTabGroup*>(aSub) != nil )
  104.         {
  105.             mTabGroup = (LTabGroup*)aSub;
  106.             break;
  107.         }
  108.         
  109.         aSub = aSub->GetSuperCommander();
  110.     }
  111. }
  112.  
  113. //---------------------------------------------------------------------------
  114. // StMPDialogHandler::FinishCreate
  115. //---------------------------------------------------------------------------
  116. //    Load in the correct initial panel and set up the initial data. We need to do
  117. // it here and not in the contstructor, because the derived-class constructor will 
  118. // have to run before we can get at the data for the panels (thru GetInitialPanelData). 
  119. // Since GetInitialPanelData is a pure virtual function we cannot have any possiblity 
  120. // that it will be called before all constructors have been called.
  121. void StMPDialogHandler::FinishCreate()
  122. {
  123.     LCommander*    defaultCommander;
  124.  
  125.     // if this window has a tab group we need to set that as the default commander
  126.     // so that tabbing works properly.
  127.     if ( mTabGroup != nil )
  128.     {
  129.         defaultCommander = LCommander::GetDefaultCommander();
  130.         LCommander::SetDefaultCommander(mTabGroup);
  131.     }
  132.     
  133.     // and then switch the panel to the new one...
  134.     mIncludeView->IncludeView((**(MPDHandle)mMPDData).MPDList[mCurrentPanelIndex-1].panelID, 
  135.                                         true);
  136.     
  137.     // Grab the panel data for the initial panel...
  138.     // and set the MPD data into the initial panel
  139.     Handle    newPanelData = GetInitialPanelData(mCurrentPanelIndex);
  140.     SignalIf_(newPanelData == nil);
  141.     mPanelDataHandles.AssignItemsAt(1, mCurrentPanelIndex, &newPanelData);
  142.     mIncludeView->UseNewPanelData(newPanelData, false);
  143.     
  144.     // reset the default commander
  145.     if ( mTabGroup != nil )
  146.     {
  147.         LCommander::SetDefaultCommander(defaultCommander);
  148.     }
  149. }
  150.  
  151. //---------------------------------------------------------------------------
  152. // StMPDialogHandler::~StMPDialogHandler
  153. //---------------------------------------------------------------------------
  154. //    Destructor
  155. StMPDialogHandler::~StMPDialogHandler()
  156. {
  157.     // Since we took posession of the handles passed back from GetXXXPanelData
  158.     // methods, we need to make sure they're disposed of properly.
  159.     for ( short i = 1; i <= (**(MPDHandle)mMPDData).numItems; i++ )
  160.     {
  161.         Handle    newPanelData = RetrievePanelData(i);
  162.         if ( newPanelData != nil )
  163.             ::DisposeHandle(newPanelData);
  164.     }
  165. }
  166.  
  167. //---------------------------------------------------------------------------
  168. // StMPDialogHandler::RetrievePanelData
  169. //---------------------------------------------------------------------------
  170. // This method gets the panel data out of the internal storage maintained by the
  171. // StMPDialogHandler class. If the data passed back is nil, the panel 
  172. // was never visited and the data has not changed.
  173. Handle StMPDialogHandler::RetrievePanelData(Int16 inPanelIndex)
  174. {
  175.     Handle    panelData;
  176.     mPanelDataHandles.FetchItemAt(inPanelIndex, &panelData);
  177.     return panelData;
  178. }
  179.  
  180. //---------------------------------------------------------------------------
  181. // StMPDialogHandler::ListenToMessage
  182. //---------------------------------------------------------------------------
  183. void StMPDialogHandler::ListenToMessage(MessageT inMessage, void* ioParam)
  184. {
  185.     StDialogHandler::ListenToMessage(inMessage, ioParam);
  186.     
  187.     switch ( inMessage )
  188.     {
  189.         case msg_MPDRevert:
  190.             HandleRevert();
  191.             break;
  192.         
  193.         case msg_MPDUseDefaults:
  194.             HandleUseDefaults();
  195.             break;
  196.  
  197.         case msg_OK:
  198.             // Before we do ANYTHING, we need to make sure that the panel is validated. We do 
  199.             // this by calling ValidatePanel which should be overidden by the panel subclass 
  200.             // to do the appropriate checking
  201.             if ( mIncludeView->ValidatePanel() )
  202.             {
  203.                 // Now that the panel has validated we can do our normal OK processing.
  204.                 HandleOK();
  205.             }
  206.             else
  207.             {
  208.                 // Panel didn't validate, so we don't want this message handled by anyone
  209.                 // else. It is as if nothing happened.
  210.                 mMessage = msg_Nothing;
  211.             }
  212.             break;
  213.             
  214.         case msg_Cancel:
  215.             HandleCancel();
  216.             break;
  217.     }
  218. }
  219.  
  220. //---------------------------------------------------------------------------
  221. // StMPDialogHandler::HandlePanelChange
  222. //---------------------------------------------------------------------------
  223. // Setup for correctly switching to a new panel. Check the validity of the old
  224. // panel data and if it's OK, switch, else tell the control to select the old
  225. // selection.
  226. void StMPDialogHandler::HandlePanelChange(Int16 inNewPanelIndex)
  227. {
  228.     // This check will not only make sure we don't try to do anything on the 
  229.     // panel if we aren't actually switching, but will prevent infinite recusion
  230.     // from the call below to SelectPanelID if the ValidatePanel call returns
  231.     // false.
  232.     if ( inNewPanelIndex != mCurrentPanelIndex )
  233.     {
  234.         // Before we do ANYTHING, we need to make sure that the panel is validated. We do 
  235.         // this by calling ValidatePanel which should be overidden by the panel subclass 
  236.         // to do the appropriate checking
  237.         if ( mIncludeView->ValidatePanel() )
  238.         {
  239.             SwitchToPanel(inNewPanelIndex);
  240.  
  241.             LPane*    aPane;
  242.             aPane = mDialog->FindPaneByID(MPD_UseDefaultsButton);
  243.             if ( aPane )    // This button doesn't have to be present
  244.             {
  245.                 if ( mIncludeView->WantDefaultsButton() )
  246.                     aPane->Enable();
  247.                 else
  248.                     aPane->Disable();
  249.             }
  250.             
  251.             aPane = mDialog->FindPaneByID(MPD_RevertButton);
  252.             if ( aPane )    // This button doesn't have to be present
  253.             {
  254.                 if ( mIncludeView->WantRevertButton() )
  255.                     aPane->Enable();
  256.                 else
  257.                     aPane->Disable();
  258.             }
  259.         }
  260.         else
  261.         {
  262.             // This will cause the control to broadcast the fact that the cell 
  263.             // has changed but this case is caught by the test above for the 
  264.             // new index being the same as the current index.
  265.             mPanelSelectControl->SelectPanelID(mCurrentPanelIndex);
  266.         }
  267.     }
  268. }
  269.  
  270. //---------------------------------------------------------------------------
  271. // StMPDialogHandler::HandleRevert
  272. //---------------------------------------------------------------------------
  273. void StMPDialogHandler::HandleRevert(void)
  274. {
  275.     Handle    newPanelData = RetrievePanelData(mCurrentPanelIndex);
  276.     SignalIf_(newPanelData == nil);
  277.     mIncludeView->UseNewPanelData(newPanelData, true);
  278. }
  279.  
  280. //---------------------------------------------------------------------------
  281. // StMPDialogHandler::HandleUseDefaults
  282. //---------------------------------------------------------------------------
  283. void StMPDialogHandler::HandleUseDefaults(void)
  284. {
  285.     Handle    newPanelData = GetPanelDefaultData(mCurrentPanelIndex);
  286.     SignalIf_(newPanelData == nil);
  287.     Try_
  288.     {
  289.         mIncludeView->UseNewPanelData(newPanelData, true);
  290.         ::DisposeHandle(newPanelData);
  291.     }
  292.     Catch_(inErr)
  293.     {
  294.         ::DisposeHandle(newPanelData);
  295.         Throw(inErr);
  296.     }
  297. }
  298.  
  299. //---------------------------------------------------------------------------
  300. // StMPDialogHandler::HandleOK
  301. //---------------------------------------------------------------------------
  302. void StMPDialogHandler::HandleOK(void)
  303. {
  304.     Handle    newPanelData = RetrievePanelData(mCurrentPanelIndex);
  305.     SignalIf_(newPanelData == nil);
  306.     mIncludeView->GetPanelData(newPanelData);
  307. }
  308.  
  309. //---------------------------------------------------------------------------
  310. // StMPDialogHandler::HandleCancel
  311. //---------------------------------------------------------------------------
  312. void StMPDialogHandler::HandleCancel(void)
  313. {
  314. }
  315.  
  316. //---------------------------------------------------------------------------
  317. // StMPDialogHandler::SwitchToPanel
  318. //---------------------------------------------------------------------------
  319. // Change the currently displayed panel in the dialog to the new one. Get the 
  320. // data from the panel being displaced and set the data for the new panel.
  321. void StMPDialogHandler::SwitchToPanel(Int16 inNewPanelIndex)
  322. {
  323.     SignalIf_(inNewPanelIndex < 1 || inNewPanelIndex > (**(MPDHandle)mMPDData).numItems);
  324.     SignalIf_(mCurrentPanelIndex < 1 || mCurrentPanelIndex > (**(MPDHandle)mMPDData).numItems);
  325.     
  326.     LCommander*    defaultCommander;
  327.  
  328.     // if this window has a tab group we need to set that as the default commander
  329.     // so that tabbing works properly.
  330.     if ( mTabGroup != nil )
  331.     {
  332.         defaultCommander = LCommander::GetDefaultCommander();
  333.         LCommander::SetDefaultCommander(mTabGroup);
  334.     }
  335.     
  336.     // Grab the panel data for the new and current panels...
  337.     // and then switch the panel to the new one, getting the updated data for the current
  338.     // panel in the process.
  339.     Handle    currPanelData = RetrievePanelData(mCurrentPanelIndex);
  340.     SignalIf_(currPanelData == nil);
  341.  
  342.     Handle    newPanelData = RetrievePanelData(inNewPanelIndex);
  343.     if ( newPanelData == nil )
  344.     {
  345.         newPanelData = GetInitialPanelData(inNewPanelIndex);
  346.         mPanelDataHandles.AssignItemsAt(1, inNewPanelIndex, &newPanelData);
  347.     }
  348.     SignalIf_(newPanelData == nil);
  349.     mIncludeView->LoadNewMPDPanel((**(MPDHandle)mMPDData).MPDList[inNewPanelIndex-1].panelID, 
  350.                                             newPanelData, currPanelData, true);
  351.     
  352.     // reset the default commander
  353.     if ( mTabGroup != nil )
  354.     {
  355.         LCommander::SetDefaultCommander(defaultCommander);
  356.     }
  357.     
  358.     // remember the panel we've switched to.
  359.     mCurrentPanelIndex = inNewPanelIndex;
  360. }
  361.  
  362.